package uf.audit.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.upload.UploadFile;
import com.opencsv.CSVReader;

import uf.audit.db.Authentic;
import uf.audit.db.Category;
import uf.audit.db.Docs;
import uf.audit.db.Marking;
import uf.audit.db.Options;
import uf.audit.db.Organize;
import uf.audit.db.Question;
import uf.audit.db.Test;
import uf.audit.db.TestModel;
import uf.audit.db.TestModelDetail;
import uf.audit.db.TestOpt;
import uf.audit.db.TestQuestion;
import uf.audit.db.User;
import uf.audit.db.WorkLevel;
import uf.audit.db.WorkSeq;
import uf.audit.db.Zjrd;
import uf.audit.util.Consts;
import uf.audit.util.Controller;
import uf.audit.util.ExecutExcel;
import uf.audit.util.ExportConfigUtil;
import uf.audit.util.MD5;
import uf.audit.util.Utils;

/**
 * 系统管理控制器类
 * 
 * @author sunny
 *
 */
@Controller(url = "/mgr", view = "/WEB-INF/pages/")
public class AdminController extends PubController {
	private static final Logger log = Logger.getLogger(AdminController.class);

	public void admin() {
		render("admin-index.html");
	}

	// 序列
	public void seq() {
		render("admin-seq.html");
	}

	public void postseqdata() {
		JSONObject obj = JSONObject.parseObject(getPostData());
		if (WorkSeq.dao.update(obj)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	public void deleteseq() {
		String seqbh = getPara("seqbh");
		if (WorkSeq.dao.delete(seqbh)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	// 分类
	public void cate() {
		render("admin-cate.html");
	}

	public void postcatedata() {
		JSONObject obj = JSONObject.parseObject(getPostData());
		if (Category.dao.update(obj)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	public void deletecate() {
		String catebh = getPara("catebh");
		if (Category.dao.delete(catebh)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	// 职级
	public void worklevel() {
		render("admin-level.html");
	}

	public void postleveldata() { // public void xxxxx() {} //protected public
									// String
		JSONObject obj = JSONObject.parseObject(getPostData());
		if (WorkLevel.dao.update(obj)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	public void deletelevel() {
		String catebh = getPara("levelbh");
		if (WorkLevel.dao.delete(catebh)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	// 机构
	public void organize() {
		render("admin-org.html");
	}

	public void postorgdata() {
		JSONObject obj = JSONObject.parseObject(getPostData());
		if (Organize.dao.update(obj)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	public void deleteorg() {
		String orgbh = getPara("orgbh");
		if (Organize.dao.delete(orgbh)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	// 人员
	public void person() {
		render("admin-person.html");
	}

	// 获取用户列表
	public void getpersonlist() {
		String dep = getPara("orgbh", null);
		renderJson(User.dao.getusers(dep));
	}

	// 删除用户
	public void deleteperson() {
		String bh = getPara("userbh", null);
		if (bh == null) {
			renderError();
		} else {
			if (User.dao.delete(bh))
				renderSuccess();
			else
				renderError();
		}
	}

	// 重置密码
	public void resetpass() {
		String bh = getPara("userbh");
		if (User.dao.resetpass(bh)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	// 修改用户状态
	public void editStatus() {
		String bh = getPara("userbh");
		int status = getParaToInt("enabled");
		if (User.dao.editStatus(bh, status)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	// 批量新增用户
	public void batchAdd() throws IOException {
		int nameIndex = 0;
		int emailIndex = 0;
		UploadFile uf = getFile("file");
		CSVReader csvReader = new CSVReader(new InputStreamReader(new FileInputStream(uf.getFile()), "GBK"));

		String[] strs = csvReader.readNext();
		if (strs != null && strs.length > 0) {
			for (int i = 0; i < strs.length; i++) {
				if (null != strs[i] && !strs[i].equals("")) {
					if (strs[i].equals("姓名")) {
						nameIndex = i;
					}
					if (strs[i].equals("电子邮件地址")) {
						emailIndex = i;
					}
				}
			}
		}

		List<String[]> list = csvReader.readAll();
		for (String[] ss : list) {
			if (null != ss[emailIndex] && !ss[emailIndex].equals("")
					&& null == User.dao.getuserByUsername(ss[emailIndex]) && null != ss[nameIndex]
					&& !ss[nameIndex].equals("")) {
				new User().set("userbh", UUID.randomUUID().toString()).set("username", ss[emailIndex])
						.set("realname", ss[nameIndex]).set("password", MD5.getStringMD5String("123456")).save();
			}
		}

		csvReader.close();
		renderSuccess();
	}

	// 题库管理
	public void questions() {
		render("admin-questions.html");
	}

	// 获取题目列表
	public void getquestions() {
		String seqbh = getPara("seqbh", null);
		String catebh = getPara("catebh", null);
		renderJson(Question.dao.getquestions(seqbh, catebh));
	}

	// 保存题目数据
	public void postquestiondata() {
		JSONObject obj = JSONObject.parseObject(getPostData());
		String bh = Question.dao.update(obj);
		renderSuccess(bh);
	}

	// 删除指定的题目
	public void deletequestion() {
		String bh = getPara("itembh", null);
		if (Question.dao.delete(bh)) {
			renderSuccess();
		} else {
			renderError();
		}
	}

	public void getoptions() {
		String bh = getPara("itembh", null);
		renderJson(Options.dao.getoptions(bh));
	}

	public void postoptions() {
		JSONArray arr = JSONArray.parseArray(getPostData());
		boolean result = true;
		for (int i = 0, j = arr.size(); i < j; i++) {
			JSONObject obj = arr.getJSONObject(i);
			result = result && Options.dao.update(obj);
		}
		if (result)
			renderSuccess();
		else
			renderError();
	}

	public void batchQuestion() {
		UploadFile file = getFile("batchFile");
		String seq = getMultiPara("sq");
		String cate = getMultiPara("ct");
		String fileName = file.getFileName();
		String filePath = file.getUploadPath();
		// 表头：难度 类型 分类 标题 选项 答案 主观题回答要点 年度
		String[] header = { "itemlevel", "itemtype", "remark", "itemcontent", "options", "answers", "keys", "nd" };
		List<List<Map<String, Object>>> content = ExecutExcel.readFromSingleExcel(filePath + File.separator + fileName,
				0, 1, 1, header);
		for (List<Map<String, Object>> rows : content) {
			JSONObject question = new JSONObject();
			JSONObject option = new JSONObject();
			question.put("itemseq", seq);
			question.put("itemcate", cate);
			String q_content = "";
			for (Map<String, Object> cols : rows) {
				for (Map.Entry<String, Object> entry : cols.entrySet()) {
					String k = entry.getKey();
					String v = String.valueOf(entry.getValue());
					if (k.equals("itemlevel")) {
						int level = 1;
						if (v.indexOf("难") >= 0) {
							level = 3;
						} else if (v.indexOf("中") >= 0 || v.indexOf("一般") >= 0) {
							level = 2;
						}
						question.put("itemlevel", level);
					} else {
						if (k.equals("itemcontent"))
							q_content = v;
						question.put(k, v);
					}
				}
			}
			Question q = Question.dao.getquestionbycontent(q_content, seq, cate); // 按内容查找，如果找到，更新，并删除答案
			if (q != null) {
				String bh = q.get("itembh");
				question.put("itembh", bh);
				Options.dao.deleteWithItembh(bh);
			}
			String bh = Question.dao.update(question);
			option.put("itembh", bh);
			if (question.getString("itemtype").indexOf("选") >= 0) {
				String optAns = question.getString("answers");
				String opts = question.getString("options");
				if (opts == null) {
					String title = question.getString("itemcontent");
					if (title == null)
						title = "";
					log.error(title + " 没有答案？");
					continue;
				}
				String optline = opts.replaceAll("\r", "").replaceAll("\n", "");
				Pattern pat = Pattern.compile(
						"^A[、|.| .|．]+(.*)B[、|.| .|．]+(.*)C[、|.| .|．]+(.*)D[、|.| .|．]+(.*?)(E[、|.| .|．]+(.*?)){0,1}(F[、|.| .|．]+(.*)){0,1}");
				Matcher m = pat.matcher(optline);
				if (m.matches()) { // A．
					option.put("optcontent", m.group(1) == null ? "" : m.group(1));
					option.put("optno", "A");
					if (optAns.indexOf("A") >= 0) {
						option.put("isanswer", 1);
					} else {
						option.put("isanswer", 0);
					}
					Options.dao.update(option);
					option.put("optcontent", m.group(2) == null ? "" : m.group(2));
					option.put("optno", "B");
					if (optAns.indexOf("B") >= 0) {
						option.put("isanswer", 1);
					} else {
						option.put("isanswer", 0);
					}
					Options.dao.update(option);
					option.put("optcontent", m.group(3) == null ? "" : m.group(3));
					option.put("optno", "C");
					if (optAns.indexOf("C") >= 0) {
						option.put("isanswer", 1);
					} else {
						option.put("isanswer", 0);
					}
					Options.dao.update(option);
					option.put("optcontent", m.group(4) == null ? "" : m.group(4));
					option.put("optno", "D");
					if (optAns.indexOf("D") >= 0) {
						option.put("isanswer", 1);
					} else {
						option.put("isanswer", 0);
					}
					Options.dao.update(option);
					if (m.group(6) != null) {
						option.put("optcontent", m.group(6) == null ? "" : m.group(6));
						option.put("optno", "E");
						if (optAns.indexOf("E") >= 0) {
							option.put("isanswer", 1);
						} else {
							option.put("isanswer", 0);
						}
						Options.dao.update(option);
					}
					if (m.group(8) != null) {
						option.put("optcontent", m.group(8) == null ? "" : m.group(8));
						option.put("optno", "F");
						if (optAns.indexOf("F") >= 0) {
							option.put("isanswer", 1);
						} else {
							option.put("isanswer", 0);
						}
						Options.dao.update(option);
					}
				}

			} else if (question.getString("itemtype").equals("判断题") || question.getString("itemtype").equals("判断")) {
				String ans = question.getString("answers");
				if (ans.toUpperCase().equals("T")) {
					option.put("optcontent", "√");
					option.put("optno", "A");
					option.put("isanswer", 1);
					Options.dao.update(option);
					option.put("optcontent", "x");
					option.put("optno", "B");
					option.put("isanswer", 0);
					Options.dao.update(option);
				} else {
					option.put("optcontent", "√");
					option.put("optno", "A");
					option.put("isanswer", 0);
					Options.dao.update(option);
					option.put("optcontent", "x");
					option.put("optno", "B");
					option.put("isanswer", 1);
					Options.dao.update(option);
				}

			} else {
				option.put("optcontent", question.getString("keys"));
				option.put("optno", "A");
				option.put("isanswer", 1);
				Options.dao.update(option);
			}
		}
		renderSuccess();
	}

	/**
	 * 计划
	 */

	public void plan() {
		render("admin-plan.html");
	}

	public void getplans() {
		String nd = getPara("nd");
		String seqbh = getPara("seqbh");
		String catebh = getPara("catebh");
		renderJson(TestModel.dao.getplans(nd, seqbh, catebh));
	}

	public void postplans() {
		JSONObject obj = JSONObject.parseObject(getPostData());
		String bh = TestModel.dao.update(obj);
		renderSuccess(bh);
	}

	public void deletewithmodelbh() {
		String bh = getPara("modelbh");
		TestModelDetail.dao.deleteWithModelbh(bh);
		renderSuccess();
	}

	public void postplandetails() {
		JSONArray arr = JSONArray.parseArray(getPostData());
		boolean result = true;
		for (int i = 0, j = arr.size(); i < j; i++) {
			JSONObject obj = arr.getJSONObject(i);
			result = result && TestModelDetail.dao.update(obj);
		}
		if (result)
			renderSuccess();
		else
			renderError();
	}

	public void getmodeldetail() {
		String bh = getPara("modelbh");
		renderJson(TestModelDetail.dao.getmodeldetails(bh));
	}

	// 试卷作废
	public void disabletest() {
		String bh = getPara("modelbh");
		TestModel model = TestModel.dao.getplan(bh);
		if (model == null) {
			renderError("没有找到试卷");
		} else {
			model.set("enabled", 1);
			model.update();
			renderSuccess();
		}
	}

	// 删除试卷
	public void deletemodel() {
		String bh = getPara("modelbh");
		TestModel model = TestModel.dao.getplan(bh);
		if (model == null) {
			renderError("没有找到试卷");
		} else {
			model.delete(bh);
			renderSuccess();
		}
	}

	// 克隆试卷
	public void cloneitem() {
		String bh = getPara("modelbh");
		TestModel model = TestModel.dao.getplan(bh);
		if (model == null) {
			renderError("没有找到试卷");
		} else {
			model.clone(bh);
			renderSuccess();
		}
	}

	// 授权管理
	public void adminauth() {
		render("admin-auth.html");
	}

	public void yjauth() {
		render("admin-yjauth.html");
	}

	public void testauth() {
		render("admin-testauth.html");
	}

	public void getauthusers() {
		int type = getParaToInt("type");
		String bh = getPara("bh");
		renderJson(User.dao.getauthenusers(type, bh));
	}

	public void deleteauthwithres() {
		int type = getParaToInt("type");
		String bh = getPara("bh");
		Authentic.dao.deleteWithResourceBh(bh, type);
		renderSuccess();
	}

	public void postauthentics() {
		JSONArray arr = JSONArray.parseArray(getPostData());
		boolean result = true;
		for (int i = 0, j = arr.size(); i < j; i++) {
			JSONObject obj = arr.getJSONObject(i);
			result = result && Authentic.dao.update(obj);
		}
		if (result)
			renderSuccess();
		else
			renderError();
	}

	/**
	 * 生成试卷
	 */

	public void buildtest() {
		String modelbh = getPara("modelbh");
		Map<String, String> info = new HashMap<String, String>();
		if (Test.dao.buildTest(modelbh, info))
			renderSuccess();
		else {
			String msg = info.get("error");
			renderError(msg);
		}
	}

	public void rebuildtest() {
		String bh = getPara("modelbh");
		if (Test.dao.modelbeused(bh)) {
			renderError("该模板已经被使用了，不能再次编辑");
		} else {
			String testbh = Test.dao.getTestWithModelBh(Consts.ADMIN_FIX, bh).getStr("testbh");
			Test.dao.deleteWithModelBh(bh);
			TestQuestion.dao.deleteWithTestBh(testbh);
			TestOpt.dao.deleteWithTestBh(testbh);
			buildtest();
		}
	}

	// 返回查看试卷的明细信息
	public void gettestoptions() {
		String testbh = getPara("testbh");
		if (testbh == null) {
			renderError();
		} else {
			renderJson(Test.dao.gettestopts(testbh));
		}
	}

	// 序列
	public void search() {
		render("admin-search.html");
	}

	// 获取成绩列表
	public void getmarkinglist() {
		String dep = getPara("orgbh", null);
		String modelbh = getPara("modelbh");
		renderJson(Marking.dao.getmarkinglist(dep, modelbh));
	}

	// 获取成绩列表
	public void exportMarking() {
		String dep = getPara("orgbh", null);
		String modelbh = getPara("modelbh");
		List<Record> markings = Marking.dao.getmarkinglist(dep, modelbh);
		String fileName = ExportConfigUtil.creatExcelUtil("考试成绩", "sheet1", "marking", markings);
		File f = new File(fileName);
		if (f.exists()) {
			renderFile(f);
		} else {
			renderError(404);
		}
	}

	// 获取题目数量
	public void gettestitemcount() {
		String itemlevel = getPara("itemlevel", null);
		String seqbh = getPara("seqbh", null);
		String itemtype = getPara("itemtype", null);
		String catebh = getPara("catebh", null);
		renderText(String.valueOf(Question.dao.getTestItemCount(itemlevel, seqbh, itemtype, catebh)));
	}

	// 删除题目
	public void deleteQuestions() {
		String idstr = getPostData().trim();
		String[] ids = idstr.split(";");
		if (Question.dao.deleteQuestions(ids))
			renderSuccess();
		else
			renderError();
	}

	// 文档管理
	public void docindex() {
		render("admin-doc.html");
	}

	// 添加文档
	public void docadd() {
		UploadFile uf = getFile("file");
		String docbh = getPara("docbh");
		String docname = getPara("docname");
		File f = null;
		if (uf != null)
			f = uf.getFile();
		if (docbh == null) {
			if (f == null) {
				redirect("/admin/docindex");
				return;
			}
			Docs.dao.update(null, docname, f.getAbsolutePath(), Utils.getLogin(this));
			redirect("/mgr/docindex");
			return;
		} else {
			if (f == null) {
				Docs.dao.update(docbh, docname, null, Utils.getLogin(this));
			} else
				Docs.dao.update(null, docname, f.getAbsolutePath(), Utils.getLogin(this));
			redirect("/mgr/docindex");
		}
	}

	// 删除文档
	public void docdelete() {
		String docbh = getPara("docbh");
		if (docbh != null && !"".equals(docbh)) {
			Docs.dao.delete(docbh);
		}
		renderSuccess();
	}

	// 职级认定
	public void zjrd() {
		render("admin-score.html");
	}

	public void gettestscore() {
		String username = getPara("username"); // modelbh=" + encodeURI($scope.currentItem.modelbh) + "&username=
		String modelbh = getPara("modelbh");
		Zjrd zjrd = Zjrd.dao.getzjrd(username, modelbh);
		if (zjrd == null) {
			zjrd = new Zjrd();
			User user = User.dao.getuserByUsernameEx(username);
			/*
			 * userbh | varchar(64) | YES | | NULL | | | username | varchar(64) | YES | |
			 * NULL | | | userno | varchar(64) | YES | | NULL | | | yzj | varchar(10) | YES
			 * | | NULL | | | sqzj | varchar(10) | YES | | NULL | | | pdzj | varchar(10) |
			 * YES | | NULL | | | pwjy | varchar(2000) | YES | | NULL | | | hrjy |
			 * varchar(2000) | YES | | NULL | | | rq | varchar(64) | YES | | NULL | | |
			 * markingbh | varchar(64) | YES | | NULL | | | modelbh | varchar(64) | YES | |
			 * NULL | | | realname | varchar(64) | YES | | NULL | | | pass
			 */
			zjrd.set("userbh", user.get("userbh"));
			zjrd.set("username", user.get("username"));
			zjrd.set("realname", user.get("realname"));
			zjrd.set("yzj", user.get("levelname"));
			zjrd.set("modelbh", modelbh);
			zjrd.set("userbh", user.get("userbh"));
		}
		renderJson(zjrd);
	}

	public void updatetestscore() {
		String jsonText = getPostData().trim();
		JSONObject obj = JSONObject.parseObject(jsonText);
		if (Zjrd.dao.update(obj)) {
			renderSuccess();
		} else {
			renderError();
		}
	}
}